package com.lxl.main;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Color;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import com.lxl.model.EnemyTank;
import com.lxl.model.MyTank;
import com.lxl.model.Wall;

/**
 * 游戏主界面
 * 
 * @author 刘星鹭
 * @Email liuxinglumail@163.com
 * @version 创建时间： 2014年10月28日 下午5:23:40
 */
public class Game extends JFrame {

	// serialVersionUID
	private static final long serialVersionUID = 4081602837014793116L;

	/**
	 * 窗体宽度
	 */
	public static final int FRAME_WIDTH = 800;
	/**
	 * 窗体高度
	 */
	public static final int FRAME_HEIGHT = 600;
	/**
	 * 窗体标题
	 */
	public static final String FRAME_TITLE = "坦克大战";
	/**
	 * 窗体字体
	 */
	public static final Font FRAME_FONT = new Font("微软雅黑", Font.PLAIN, 12);
	/**
	 * 窗体是否总在最前
	 */
	public static final boolean FRAME_ALWAYS_ON_TOP = false;
	/**
	 * 标题栏高度
	 */
	public static final int HEADER_HEIGHT = 28;
	/**
	 * 窗体初始位置设置为屏幕中心
	 */
	public static final Point FRAME_POSITION = new Point(Toolkit
			.getDefaultToolkit().getScreenSize().width / 2 - FRAME_WIDTH / 2,
			Toolkit.getDefaultToolkit().getScreenSize().height / 2
					- FRAME_HEIGHT / 2);
	/**
	 * 窗体背景颜色
	 */
	public static final Color FRAME_BACKGROUND = Color.BLACK;
	/**
	 * 窗体是否可以改变大小
	 */
	public static final boolean FRAME_RESIZEABLE = false;
	/**
	 * 敌人坦克数量
	 */
	public static final int ENEMY_TANK_COUNT = 5;
	/**
	 * 双缓冲图片
	 */
	private Image offScreenImage = null;
	/**
	 * 新建一个主角坦克
	 */
	private MyTank myTank = new MyTank();
	/**
	 * 新建一批敌人坦克
	 */
	private ArrayList<EnemyTank> enemyTanks = new ArrayList<EnemyTank>();
	/**
	 * 新建一堵墙
	 */
	private Wall wall = new Wall();

	/**
	 * main方法
	 * 
	 * @param args
	 *            没用的参数
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Game frame = new Game();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * 无参构造方法
	 */
	public Game() {
		// 初始化所有敌人坦克
		for (int i = 0; i < ENEMY_TANK_COUNT; i++) {
			enemyTanks.add(new EnemyTank());
		}
		// 设置窗体初始位置
		setLocation(FRAME_POSITION);
		// 设置窗体是否总在最前
		setAlwaysOnTop(FRAME_ALWAYS_ON_TOP);
		// 设置窗体的背景颜色
		getContentPane().setBackground(FRAME_BACKGROUND);
		// 设置窗体是否可以更改大小
		setResizable(FRAME_RESIZEABLE);
		// 设置窗体大小
		setSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
		// 设置窗体标题
		setTitle(FRAME_TITLE);
		// 设置字体
		setFont(FRAME_FONT);
		// 设置窗体关闭按钮默认操作
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 添加键盘监听器
		addKeyListener(new KeyListener());
		// 启动重画线程
		new Thread(new PaintTask()).start();
		// 启动监听子弹发射间隔的线程
		new Thread(new ShootTask()).start();
	}

	/**
	 * 重写paint方法
	 */
	@Override
	public void paint(Graphics graphics) {
		// 判断敌人是不是死了，死了就从容器中除去
		for (int i = 0; i < enemyTanks.size(); i++) {
			if (!enemyTanks.get(i).isAlive())
				enemyTanks.remove(i);
		}
		// 双缓冲消除闪烁
		offScreenImage = createImage(FRAME_WIDTH, FRAME_HEIGHT);
		Graphics offScreenImageGraphics = offScreenImage.getGraphics();
		offScreenImageGraphics.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT);
		super.paint(offScreenImageGraphics);
		// 画出墙
		wall.draw(offScreenImageGraphics);
		// 画出主角坦克
		myTank.paint(offScreenImageGraphics);
		// 画一批敌人坦克
		for (int i = 0; i < enemyTanks.size(); i++)
			enemyTanks.get(i).paint(offScreenImageGraphics);
		// 判断是否击中敌人
		myTank.hit(enemyTanks);
		// 判断是否被击中
		for (int i = 0; i < enemyTanks.size(); i++)
			enemyTanks.get(i).hit(myTank);
		// 判断是否击中墙
		for (int i = 0; i < myTank.getThisBullets().size(); i++)
			myTank.getThisBullets().get(i).hitWall(wall);
		// 判断大子弹是否击中墙
		for (int i = 0; i < myTank.getThisBigBullets().size(); i++)
			myTank.getThisBigBullets().get(i).hitWall(wall);
		// 判断敌人是否击中墙
		for (int i = 0; i < enemyTanks.size(); i++) {
			for (int j = 0; j < enemyTanks.get(i).getThisBullets().size(); j++)
				enemyTanks.get(i).getThisBullets().get(j).hitWall(wall);
		}
		// 判断是否撞墙
		myTank.hitWall(wall);
		// 判断敌人是否撞墙
		for (int i = 0; i < enemyTanks.size(); i++) {
			enemyTanks.get(i).hitWall(wall);
		}
		// 在敌人数大于1的时候才判断
		if (enemyTanks.size() > 1) {
			// 判断敌人是否撞到了自己人
			for (int i = 0; i < enemyTanks.size(); i++)
				enemyTanks.get(i).hitFriends(enemyTanks);
		}
		// 双缓冲消除闪烁
		graphics.drawImage(offScreenImage, 0, 0, null);
	}

	/**
	 * 用于重画的内部类
	 */
	private class PaintTask implements Runnable {
		/**
		 * 重写run方法
		 */
		@Override
		public void run() {
			while (true) {
				// 如果你死了就弹出对话框，结束游戏
				if (!myTank.isAlive()) {
					JOptionPane.showMessageDialog(null, "你死了！请重新开始游戏");
					System.exit(0);
				}
				// 如果敌人全死了就弹出对话框，结束游戏
				for (int i = 0; i < enemyTanks.size(); i++) {
					if (enemyTanks.get(i).isAlive())
						break;
					if (i == enemyTanks.size() - 1) {
						JOptionPane.showMessageDialog(null, "你赢了！请重新开始游戏");
						System.exit(0);
					}
				}
				// 重画
				repaint();
				try {
					// 每隔10毫秒重画一次
					Thread.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 用于防止子弹发射间隔过低的内部类
	 */
	private class ShootTask implements Runnable {
		/**
		 * 重写run方法
		 */
		@Override
		public void run() {
			while (true) {
				myTank.setShootedFlag(false);
				for (int i = 0; i < enemyTanks.size(); i++)
					enemyTanks.get(i).setShootedFlag(false);
				try {
					// 每隔500毫秒允许发射一枚子弹
					Thread.sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 用于监听键盘事件的内部类
	 */
	private class KeyListener extends KeyAdapter {
		/**
		 * 重写keyPressed方法
		 */
		@Override
		public void keyPressed(KeyEvent e) {
			// 调用MyTank类中的keyPressed方法
			myTank.keyPressed(e);
			// 继承父类的方法
			super.keyPressed(e);
		}

		/**
		 * 重写keyReleased方法
		 */
		@Override
		public void keyReleased(KeyEvent e) {
			// 调用MyTank类中的keyReleased方法
			myTank.keyReleased(e);
			// 继承父类的方法
			super.keyReleased(e);
		}
	}
}